#include "StdAfx.h"
#include "RollbackAction.h"
#include "MediawikiXmlReader.h"
#include "collabrc.h"

CRollbackAction::CRollbackAction(unsigned int diff, QString page):m_diff(diff),m_page(page)
{
}

CRollbackAction::~CRollbackAction(void)
{
}

bool CRollbackAction::Run()
{
	CLoggedEvent *event = new CLoggedEvent(CLoggedEvent::PROGRESS, "Rollback", "Acquiring rollback token for " + m_page);
	emit EventPosted(event);

	QNetworkAccessManager& manager = CollabRC::GetNetworkManager();

	QString uri;
	QEventLoop loop;

	QTextStream uriStream(&uri);
	uriStream	<< "http://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvtoken=rollback&revids=" 
				<< m_diff 
				<< "&format=xml";

	QNetworkRequest tokenRequest = CollabRC::CreateNetworkRequest(uri);
	QNetworkReply* reply = manager.get(tokenRequest);
	
	// Wait for the response
	QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
	loop.exec();
	
	CMediawikiXmlReader xmlHandler(NULL);
	QXmlSimpleReader xmlReader;
	QXmlInputSource source(reply);
	xmlReader.setContentHandler(&xmlHandler);
	xmlReader.parse(source);

	// Check for errors
	if (xmlHandler.errorOccurred())
	{
		// TODO: NYI
		__asm int 3h;
	}

	event->UpdateMessage("Rolling back page " + m_page);

	delete reply;

	QString uri2;
	QTextStream uriStream2(&uri2);
	uriStream2	<< "http://en.wikipedia.org/w/api.php?action=rollback&format=xml&user="
				<< xmlHandler.GetUserName()
				<< "&title="
				<< xmlHandler.GetPageName();
				
	QString postData;
	QTextStream dataStream(&postData);

	dataStream << "token="
		<< QUrl::toPercentEncoding(xmlHandler.GetRollbackToken())
		<< "&summary="
		<< QUrl::toPercentEncoding("Reverted edits by [[Special:Contributions/")
		<< QUrl::toPercentEncoding(xmlHandler.GetUserName())
		<< QUrl::toPercentEncoding("|")
		<< QUrl::toPercentEncoding(xmlHandler.GetUserName())
		<< QUrl::toPercentEncoding("]] " + CollabRC::GetSummaryTag());
	

	QNetworkRequest rollbackOperation(uri2);
	QNetworkReply *reply2 = manager.post(rollbackOperation, postData.toAscii());
	
	// Wait for response
	QObject::connect(reply2, SIGNAL(finished()), &loop, SLOT(quit()));
	loop.exec();

	// Check for error
	QXmlInputSource source2(reply2);
	xmlReader.parse(source2);
	if (!xmlHandler.errorOccurred())
	{
		// Feed back "bad" result
		emit RollbackSucceeded(m_diff);
		event->UpdateMessage("Rolled back " + m_page);
		event->UpdateStatus(CLoggedEvent::COMPLETE);
	}
	else 
	{
		emit RollbackFailed(m_diff, xmlHandler.GetErrorCode(), xmlHandler.GetError());
		event->UpdateMessage("Could not roll back " + m_page + ": " + xmlHandler.GetError());
		event->UpdateStatus(CLoggedEvent::ERROR);
	}

	// TODO: Handle this deletion correctly
	// event->deleteLater();
	return !xmlHandler.errorOccurred();


}

bool CRollbackAction::Complete()
{
	// No action
	return true;
}